using Senparc.Weixin.Exceptions;
using Senparc.Weixin.Open.Entities;
using System;
using System.Collections.Generic;
namespace Senparc.Weixin.Open.CommonAPIs
{
	public class PreAuthCodeContainer
	{
		private static Dictionary<string, PreAuthCodeBag> PreAuthCodeCollection = new Dictionary<string, PreAuthCodeBag>(StringComparer.OrdinalIgnoreCase);
		public static void Register(string componentAppId, string componentAppSecret)
		{
			PreAuthCodeContainer.PreAuthCodeCollection[componentAppId] = new PreAuthCodeBag
			{
				ComponentAppId = componentAppId,
				ComponentAppSecret = componentAppSecret,
				ExpireTime = DateTime.MinValue,
				PreAuthCodeResult = new PreAuthCodeResult()
			};
		}
		public static string TryGetToken(string componentAppId, string componentAppSecret, string componentVerifyTicket, bool getNewToken = false)
		{
			if (!PreAuthCodeContainer.CheckRegistered(componentAppId) || getNewToken)
			{
				PreAuthCodeContainer.Register(componentAppId, componentAppSecret);
			}
			return PreAuthCodeContainer.GetToken(componentAppId, componentVerifyTicket, false);
		}
		public static string GetToken(string componentAppId, string componentVerifyTicket, bool getNewToken = false)
		{
			return PreAuthCodeContainer.GetTokenResult(componentAppId, componentVerifyTicket, getNewToken).pre_auth_code;
		}
		public static PreAuthCodeResult GetTokenResult(string componentAppId, string componentVerifyTicket, bool getNewToken = false)
		{
			if (!PreAuthCodeContainer.PreAuthCodeCollection.ContainsKey(componentAppId))
			{
				throw new WeixinException("此appId尚未注册，请先使用PreAuthCodeContainer.Register完成注册（全局执行一次即可）！");
			}
			PreAuthCodeBag preAuthCodeBag = PreAuthCodeContainer.PreAuthCodeCollection[componentAppId];
			lock (preAuthCodeBag.Lock)
			{
				if (getNewToken || preAuthCodeBag.ExpireTime <= DateTime.Now)
				{
					preAuthCodeBag.PreAuthCodeResult = CommonApi.GetPreAuthCode(preAuthCodeBag.ComponentAppId, preAuthCodeBag.ComponentAppSecret, componentVerifyTicket, 10000);
					preAuthCodeBag.ExpireTime = DateTime.Now.AddSeconds((double)preAuthCodeBag.PreAuthCodeResult.expires_in);
				}
			}
			return preAuthCodeBag.PreAuthCodeResult;
		}
		public static bool CheckRegistered(string componentAppId)
		{
			return PreAuthCodeContainer.PreAuthCodeCollection.ContainsKey(componentAppId);
		}
	}
}
